﻿#include "app_anim.h"

static uint32_t app_anim_time = 500;
static lv_anim_path_cb_t app_anim_path = lv_anim_path_ease_out;
static app_anim_type_e app_anim_type = LOAD_ANIM_OVER_LEFT;

static void lv_anim_set_y(void* obj, int32_t v) {
    lv_obj_set_y((lv_obj_t*)obj, v);
}

int32_t lv_anim_get_y(void* obj) {
    return (int32_t)lv_obj_get_y((lv_obj_t*)obj);
}

static void lv_anim_set_x(void* obj, int32_t v) {
    lv_obj_set_x((lv_obj_t*)obj, v);
}

int32_t lv_anim_get_x(void* obj) {
    return (int32_t)lv_obj_get_x((lv_obj_t*)obj);
}

static void lv_anim_set_bg_opa(void* obj, int32_t v) {
    lv_obj_set_style_bg_opa((lv_obj_t*)obj, (lv_opa_t)v, LV_PART_MAIN);
}

int32_t lv_anim_get_bg_opa(void* obj) {
    return (int32_t)lv_obj_get_style_bg_opa((lv_obj_t*)obj, LV_PART_MAIN);
}

void app_anim_set_global(app_anim_type_e type, uint32_t time, lv_anim_path_cb_t path) {
    app_anim_type = type;
    app_anim_time = time;
    app_anim_path = path;
}

/// 动画参数初始化
void app_anim_init_attr(app_anim_attr_t* attr) {
    lv_coord_t hor = LV_HOR_RES;
    lv_coord_t ver = LV_VER_RES;

    switch (app_anim_type)
    {
    case LOAD_ANIM_OVER_LEFT:
        attr->drag_dir = ROOT_DRAG_DIR_HOR;

        attr->push.enter.start = hor;
        attr->push.enter.end = 0;
        attr->push.exit.start = 0;
        attr->push.exit.end = 0;

        attr->pop.enter.start = 0;
        attr->pop.enter.end = 0;
        attr->pop.exit.start = 0;
        attr->pop.exit.end = hor;
        break;

    case LOAD_ANIM_OVER_RIGHT:
        attr->drag_dir = ROOT_DRAG_DIR_HOR;

        attr->push.enter.start = -hor;
        attr->push.enter.end = 0;
        attr->push.exit.start = 0;
        attr->push.exit.end = 0;

        attr->pop.enter.start = 0;
        attr->pop.enter.end = 0;
        attr->pop.exit.start = 0;
        attr->pop.exit.end = -hor;
        break;

    case LOAD_ANIM_OVER_TOP:
        attr->drag_dir = ROOT_DRAG_DIR_VER;

        attr->push.enter.start = ver;
        attr->push.enter.end = 0;
        attr->push.exit.start = 0;
        attr->push.exit.end = 0;

        attr->pop.enter.start = 0;
        attr->pop.enter.end = 0;
        attr->pop.exit.start = 0;
        attr->pop.exit.end = ver;
        break;

    case LOAD_ANIM_OVER_BOTTOM:
        attr->drag_dir = ROOT_DRAG_DIR_VER;

        attr->push.enter.start = -ver;
        attr->push.enter.end = 0;
        attr->push.exit.start = 0;
        attr->push.exit.end = 0;

        attr->pop.enter.start = 0;
        attr->pop.enter.end = 0;
        attr->pop.exit.start = 0;
        attr->pop.exit.end = -ver;
        break;

    case LOAD_ANIM_MOVE_LEFT:
        attr->drag_dir = ROOT_DRAG_DIR_HOR;

        attr->push.enter.start = hor;
        attr->push.enter.end = 0;
        attr->push.exit.start = 0;
        attr->push.exit.end = -hor;

        attr->pop.enter.start = -hor;
        attr->pop.enter.end = 0;
        attr->pop.exit.start = 0;
        attr->pop.exit.end = hor;
        break;

    case LOAD_ANIM_MOVE_RIGHT:
        attr->drag_dir = ROOT_DRAG_DIR_HOR;

        attr->push.enter.start = -hor;
        attr->push.enter.end = 0;
        attr->push.exit.start = 0;
        attr->push.exit.end = hor;

        attr->pop.enter.start = hor;
        attr->pop.enter.end = 0;
        attr->pop.exit.start = 0;
        attr->pop.exit.end = -hor;
        break;

    case LOAD_ANIM_MOVE_TOP:
        attr->drag_dir = ROOT_DRAG_DIR_VER;

        attr->push.enter.start = ver;
        attr->push.enter.end = 0;
        attr->push.exit.start = 0;
        attr->push.exit.end = -ver;

        attr->pop.enter.start = -ver;
        attr->pop.enter.end = 0;
        attr->pop.exit.start = 0;
        attr->pop.exit.end = ver;
        break;

    case LOAD_ANIM_MOVE_BOTTOM:
        attr->drag_dir = ROOT_DRAG_DIR_VER;

        attr->push.enter.start = -ver;
        attr->push.enter.end = 0;
        attr->push.exit.start = 0;
        attr->push.exit.end = ver;

        attr->pop.enter.start = ver;
        attr->pop.enter.end = 0;
        attr->pop.exit.start = 0;
        attr->pop.exit.end = -ver;
        break;

    case LOAD_ANIM_FADE_ON:
        attr->drag_dir = ROOT_DRAG_DIR_NONE;

        attr->push.enter.start = LV_OPA_TRANSP;
        attr->push.enter.end = LV_OPA_COVER;
        attr->push.exit.start = LV_OPA_COVER;
        attr->push.exit.end = LV_OPA_COVER;

        attr->pop.enter.start = LV_OPA_COVER;
        attr->pop.enter.end = LV_OPA_COVER;
        attr->pop.exit.start = LV_OPA_COVER;
        attr->pop.exit.end = LV_OPA_TRANSP;
        break;

    case LOAD_ANIM_NONE:
        memset(attr, 0, sizeof(app_anim_attr_t));
        return true;

    default:
        return false;
    }

    /* Determine the setter and getter of the animation */
    if (attr->drag_dir == ROOT_DRAG_DIR_HOR)
    {
        attr->setter = lv_anim_set_x;
        attr->getter = lv_anim_get_x;
    }
    else if (attr->drag_dir == ROOT_DRAG_DIR_VER)
    {
        attr->setter = lv_anim_set_y;
        attr->getter = lv_anim_get_y;
    }
    else
    {
        attr->setter = lv_anim_set_bg_opa;
        attr->getter = lv_anim_get_bg_opa;
    }

    return true;
}

/// 动画初始化
void app_anim_init(lv_anim_t* a, app_anim_attr_t* attr) {
    lv_anim_init(a);

    lv_anim_set_time(&a, app_anim_time);
    lv_anim_set_path_cb(&a, app_anim_path);

    app_anim_init_attr(attr);

    lv_anim_set_exec_cb(&a, attr->setter);
}

app_anim_type_e app_anim_get_type() {
    return app_anim_type;
}
